#include	"monitor.h"
#include	"common.h"
#include	"dt.h"
#include	"timer.h"
#include	"paging.h"
#include	"kheap.h"
#include	"task.h"
#include	"syscall.h"

extern u32int placement_addr;
extern struct page_directory *kernel_directory;
extern struct page_directory *current_directory;
u32int initial_esp;

u8int flag_task;

int main(struct multiboot *mboot_ptr, u32int initial_stack){

	int tid;

	initial_esp = initial_stack;
	flag_task = 0;

	init_dt();

	monitor_clear();
	asm volatile("sti");
	init_timer(50);

	monitor_write("system initializing...placement = ");
	monitor_write_hex(placement_addr);
	monitor_write("\n\n");

	monitor_write("Initial ebp = ");
	monitor_write_hex(read_ebp());
	monitor_write("\n");

	init_paging();
	init_tasking();

	flag_task = 1;

	monitor_write("Memory management initialized. placement = ");
	monitor_write_hex(placement_addr);
	monitor_write("\n");

	tid = fork();
	
	if(tid == 0){
		monitor_write("Initializing syscalls...\n");
		init_syscalls();

		monitor_write("Switching to user mode...");
		switch_to_usermode();
		syscall_monitor_write("Done.\n");

		syscall_monitor_write("[init] ebp = ");
		syscall_monitor_write_hex((u32int)read_ebp());
		syscall_monitor_write("\n");

		int ret = syscall_fork();
		int i;
		if(ret == 0){
			for(i = 0; i < 16; i++)
				syscall_monitor_write("b");
			syscall_monitor_write("\n");
			syscall_monitor_write("[child][forked] ebp = ");
			syscall_monitor_write_hex((u32int)read_ebp());
			syscall_monitor_write("\n");
		}else{
			for(i = 0; i < 16; i++)
				syscall_monitor_write("a");
			syscall_monitor_write("\n");
			syscall_monitor_write("[init][forked] ebp = ");
			syscall_monitor_write_hex((u32int)read_ebp());
			syscall_monitor_write("\n");
		}
	}else{
		sched();
	}
	
	return 0;
}
